package MybatisDemo;

import Anno.ReturnType;
import Anno.Select;
import org.dom4j.DocumentException;
import java.beans.PropertyVetoException;
import java.io.FileNotFoundException;
import java.lang.reflect.*;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

public class sqlSession
{
	Configs configs = new Configs();

	public sqlSession() throws DocumentException, FileNotFoundException, PropertyVetoException
	{
		configs.read();
		configs.CreateDataSource();
	}

	//获取pojo类的代理对象
	public <T> T getMapperObject(Class<T> clazz)
	{
		ClassLoader classLoader = this.getClass().getClassLoader();
		Class<?>[] interfaces = {clazz};
		T obj = (T) Proxy.newProxyInstance(classLoader,
				interfaces,
				new InvocationHandler()
				{
					@Override
					public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
					{
						String interfaceName = configs.getMappingClassName();
						Class clazz = Class.forName(interfaceName);
						Method[] methods = clazz.getDeclaredMethods();
						//方法注解中的sql语句及返回值
						String sql = "";
						String return_type = "";
						for(Method m : methods)
						{
							//解析方法注解
							boolean boo1 = method.isAnnotationPresent(Select.class);
							boolean boo2 = method.isAnnotationPresent(ReturnType.class);
							if(boo1)
							{
								//获取对应注解对象
								Select select = method.getAnnotation(Select.class);
								ReturnType returnType = method.getAnnotation(ReturnType.class);
								System.out.println(select.value());
								System.out.println(returnType.value());
								sql = select.value();
								return_type = returnType.value();
							}
						}
						Connection conn = configs.getconnection();
						List list = QueryTable(sql, Class.forName(return_type), conn);
						return list;
					}
				}

		);
		return obj;
	}

	<T> List<T> QueryTable(String sql, Class<T> clazz, Connection conn) throws SQLException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException
	{
		List<T> list = new ArrayList();
		PreparedStatement preparedStatement = conn.prepareStatement(sql);
		ResultSet resultSet = preparedStatement.executeQuery();
		Field[] fields = clazz.getDeclaredFields();
		while (resultSet.next())
		{
			T obj = clazz.getDeclaredConstructor().newInstance();
			for(Field field : fields)
			{
				field.setAccessible(true);
				Object value = resultSet.getObject(field.getName());
				field.set(obj, value);
			}
			list.add(obj);
		}
		resultSet.close();
		preparedStatement.close();
		conn.close();
		return list;
	}

}
